package utils

import (
	"boy-go/modules/generator/constants"
	"boy-go/modules/generator/model"
	"strconv"
	"strings"
)

type name struct {
}

func InitTable(genTable *model.GenTable, operName string) {
	packageName := "system"
	moduleName := "system"
	businessName := *genTable.MTableName
	genType := "0"
	tplWebType := "element-plus"
	genTable.ClassName = convertStructName(*genTable.MTableName)
	genTable.ModuleName = convertStructName(*genTable.MTableName)
	genTable.PackageName = &packageName
	genTable.BusinessName = &businessName
	genTable.ModuleName = &moduleName
	genTable.FunctionAuthor = &operName
	genTable.FunctionName = replaceText(genTable.MTableComment)
	genTable.GenType = &genType
	genTable.TplWebType = &tplWebType
	genTable.TplCategory = &constants.TPL_CRUD

	genTable.CreateBy = &operName

}
func InitColumnField(column *model.GenTableColumn, table *model.GenTable) {
	dataType := getDbType(column.ColumnType)
	columnName := column.ColumnName
	structField := toCamelCase(columnName)
	structType := dateType2FieldType(dataType)
	column.TableId = table.TableId
	column.CreateBy = table.CreateBy
	column.StructField = toUpperFirst(structField)
	column.StructType = structType
	column.QueryType = constants.QUERY_EQ
	if arraysContains(constants.COLUMNTYPE_STR, dataType) || arraysContains(constants.COLUMNTYPE_TEXT, dataType) {
		// 字符串长度超过500设置为文本域
		columnLength := getColumnLength(column.ColumnType)
		if columnLength >= 500 || arraysContains(constants.COLUMNTYPE_TEXT, dataType) {
			column.HtmlType = constants.HTML_TEXTAREA
		} else {
			column.HtmlType = constants.HTML_INPUT
		}
	} else if arraysContains(constants.COLUMNTYPE_TIME, dataType) {
		// 时间类型转换
		column.HtmlType = constants.HTML_DATETIME
	} else if arraysContains(constants.COLUMNTYPE_NUMBER, dataType) {
		// 数字类型转换
		column.HtmlType = constants.HTML_INPUT
	}
	// 插入字段（默认所有字段都需要插入）
	column.IsInsert = constants.REQUIRE
	// 编辑字段
	if !arraysContains(constants.COLUMNNAME_NOT_EDIT, columnName) && (column.IsPk != "1") {
		column.IsEdit = constants.REQUIRE
	}
	// 列表字段
	if !arraysContains(constants.COLUMNNAME_NOT_LIST, columnName) && (column.IsPk != "1") {
		column.IsList = constants.REQUIRE
	}
	// 查询字段
	if !arraysContains(constants.COLUMNNAME_NOT_QUERY, columnName) && (column.IsPk != "1") {
		column.IsQuery = constants.REQUIRE
	}
	// 查询字段类型
	if endsWithIgnoreCase(columnName, "name") {
		column.QueryType = constants.QUERY_LIKE
	}
	//状态字段设置单选框
	if endsWithIgnoreCase(columnName, "status") || endsWithIgnoreCase(columnName, "state") {
		column.HtmlType = constants.HTML_RADIO
	} else if endsWithIgnoreCase(columnName, "type") || endsWithIgnoreCase(columnName, "sex") {
		column.HtmlType = constants.HTML_SELECT
	} else if endsWithIgnoreCase(columnName, "image") {
		column.HtmlType = constants.HTML_IMAGE_UPLOAD
	} else if endsWithIgnoreCase(columnName, "file") {
		column.HtmlType = constants.HTML_FILE_UPLOAD
	} else if endsWithIgnoreCase(columnName, "content") {
		column.HtmlType = constants.HTML_EDITOR
	}

}

// convertStructName 表名转换结构体名称
func convertStructName(tableName string) *string {
	parts := strings.Split(tableName, "_")
	for i, part := range parts {
		// 将每个单词首字母大写
		parts[i] = strings.Title(part)
	}
	structName := strings.Join(parts, "")
	return &structName
}

// getDbType 获取数据库类型字段
func getDbType(columnType string) string {
	//判断是否存在()截取(之前的
	if index := strings.Index(columnType, "("); index > 0 {
		columnType = columnType[0:index]
	}
	return columnType
}

func getColumnLength(columnType string) int {
	length := 0
	if index := strings.Index(columnType, "("); index > 0 {
		dataType := columnType[0:index]
		length = strings.Index(columnType, ")")
		if length > 0 {
			dataType = columnType[index+1 : length]
			length, _ = strconv.Atoi(dataType)
		}
	}
	return length
}

// ToCamelCase 驼峰式命名法 例如：user_name->userName
func toCamelCase(s string) string {
	parts := strings.Split(s, "_")
	for i, part := range parts {
		if i == 0 {
			parts[i] = strings.ToLower(part)
		} else {
			parts[i] = strings.Title(part)
		}
	}
	return strings.Join(parts, "")
}

func dateType2FieldType(dataType string) string {
	switch dataType {
	case "int":
		return "int64"
	case "float":
		return "float64"
	case "double":
		return "float64"
	case "date":
		return "time.Time"
	case "bigint":
		return "int64"
	case "tinyint":
		return "int"
	case "decimal":
		return "float64"
	case "datetime":
		return "time.Time"
	default:
		return "string"
	}
}
